home *** CD-ROM | disk | FTP | other *** search
/ MacWorld: Complete Mac Interactive / Macworld Complete Mac Interactive CD)(1994).iso / The Best of BMUG / Entertainment / Strategy / Bolo / Bolo Utilities / BoloBrains / Terminator Brain / debug.c < prev    next >
Text File  |  1993-07-01  |  5KB  |  229 lines

  1. /* Parts of this code (C) Symantec */
  2. #include <macheaders>
  3. #include <stdarg.h>
  4. #include "debug.h"
  5.  
  6. static strlen(char *s)
  7.     {
  8.     int i=0;
  9.     while (*s++) i++;
  10.     return(i);
  11.     }
  12.  
  13. static struct format
  14.     {
  15.     unsigned         leftJustify : 1;
  16.     unsigned         forceSign : 1;
  17.     unsigned         altForm : 1;
  18.     unsigned         zeroPad : 1;
  19.     unsigned         havePrecision : 1;
  20.     unsigned         hSize : 1;
  21.     unsigned         lSize : 1;
  22.     unsigned         LSize : 1;
  23.     char            sign;
  24.     char            exponent;
  25.     int                fieldWidth;
  26.     int                precision;
  27.     } default_format;
  28.  
  29. struct decrec
  30.     {
  31.     char            sgn;
  32.     short            exp;
  33. //    char            sig[SIGDIGLEN];
  34.     short            pad;
  35.     // following fields aren't used by SANE
  36.     short            min;
  37.     short            dot;
  38.     short            max;
  39.     };
  40.  
  41. #define BUFLEN            512
  42.  
  43. static int vsprintf(char *sbuffer, char *fmt, va_list arg)
  44.     {
  45.     register int c, i, j, nwritten = 0;
  46.     register unsigned long n;
  47.     register char *s;
  48.     char buf[BUFLEN], *digits, *t;
  49.     struct format F;
  50.     struct decrec D;
  51.  
  52.     for (c = *fmt; c; c = *++fmt)
  53.         {
  54.         if (c != '%') goto copy1;
  55.         F = default_format;
  56.  
  57.             //  decode flags
  58.  
  59.         for (;;)
  60.             {
  61.             c = *++fmt;
  62.             if      (c == '-')    F.leftJustify = true;
  63.             else if (c == '+')    F.forceSign = true;
  64.             else if (c == ' ')    F.sign = ' ';
  65.             else if (c == '#')    F.altForm = true;
  66.             else if (c == '0')    F.zeroPad = true;
  67.             else break;
  68.             }
  69.  
  70.             //  decode field width
  71.  
  72.         if (c == '*')
  73.             {
  74.             if ((F.fieldWidth = va_arg(arg, int)) < 0)
  75.                 {
  76.                 F.leftJustify = true;
  77.                 F.fieldWidth = -F.fieldWidth;
  78.                 }
  79.             c = *++fmt;
  80.             }
  81.         else
  82.             {
  83.             for (; c >= '0' && c <= '9'; c = *++fmt)
  84.                 F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
  85.             }
  86.  
  87.             //  decode precision
  88.  
  89.         if (c == '.')
  90.             {
  91.             if ((c = *++fmt) == '*')
  92.                 { F.precision = va_arg(arg, int); c = *++fmt; }
  93.             else for (; c >= '0' && c <= '9'; c = *++fmt)
  94.                     F.precision = (10 * F.precision) + (c - '0');
  95.             if (F.precision >= 0) F.havePrecision = true;
  96.             }
  97.  
  98.             //  perform appropriate conversion
  99.  
  100.         s = &buf[BUFLEN];
  101.         if (F.leftJustify) F.zeroPad = false;
  102.  
  103. conv:    switch (c)
  104.             {
  105.             case 'h' :    F.hSize = true; c = *++fmt; goto conv;
  106.             case 'l' :    F.lSize = true; c = *++fmt; goto conv;
  107.             case 'L' :    F.LSize = true; c = *++fmt; goto conv;
  108.             case 'd' :
  109.             case 'i' :    if (F.lSize) n = va_arg(arg, long);
  110.                         else n = va_arg(arg, int);
  111.                         if (F.hSize) n = (short) n;
  112.                         if ((long) n < 0) { n = -n; F.sign = '-'; }
  113.                         else if (F.forceSign) F.sign = '+';
  114.                         goto decimal;
  115.             case 'u' :    if (F.lSize) n = va_arg(arg, unsigned long);
  116.                         else n = va_arg(arg, unsigned int);
  117.                         if (F.hSize) n = (unsigned short) n;
  118.                         F.sign = 0;
  119.                         goto decimal;
  120.             decimal:    if (!F.havePrecision)
  121.                             {
  122.                             if (F.zeroPad)
  123.                                 {
  124.                                 F.precision = F.fieldWidth;
  125.                                 if (F.sign) --F.precision;
  126.                                 }
  127.                             if (F.precision < 1) F.precision = 1;
  128.                             }
  129.                         for (i = 0; n; n /= 10, i++) *--s = n % 10 + '0';
  130.                         for (; i < F.precision; i++) *--s = '0';
  131.                         if (F.sign) { *--s = F.sign; i++; }
  132.                         break;
  133.  
  134.             case 'o' :    if (F.lSize) n = va_arg(arg, unsigned long);
  135.                         else n = va_arg(arg, unsigned int);
  136.                         if (F.hSize) n = (unsigned short) n;
  137.                         if (!F.havePrecision)
  138.                             {
  139.                             if (F.zeroPad) F.precision = F.fieldWidth;
  140.                             if (F.precision < 1) F.precision = 1;
  141.                             }
  142.                         for (i = 0; n; n /= 8, i++) *--s = n % 8 + '0';
  143.                         if (F.altForm && i && *s != '0') { *--s = '0'; i++; }
  144.                         for (; i < F.precision; i++) *--s = '0';
  145.                         break;
  146.  
  147.             case 'p' :    F.havePrecision = F.lSize = true;
  148.                         F.precision = 8;
  149.             case 'X' :    digits = "0123456789ABCDEF";
  150.                         goto hexadecimal;
  151.             case 'x' :    digits = "0123456789abcdef";
  152.             hexadecimal:if (F.lSize) n = va_arg(arg, unsigned long);
  153.                         else n = va_arg(arg, unsigned int);
  154.                         if (F.hSize) n = (unsigned short) n;
  155.                         if (!F.havePrecision)
  156.                             {
  157.                             if (F.zeroPad)
  158.                                 {
  159.                                 F.precision = F.fieldWidth;
  160.                                 if (F.altForm) F.precision -= 2;
  161.                                 }
  162.                             if (F.precision < 1) F.precision = 1;
  163.                             }
  164.                         for (i = 0; n; n /= 16, i++) *--s = digits[n % 16];
  165.                         for (; i < F.precision; i++) *--s = '0';
  166.                         if (F.altForm) { *--s = c; *--s = '0'; i += 2; }
  167.                         break;
  168.  
  169.             case 'c' :    *--s = va_arg(arg, int); i = 1; break;
  170.  
  171.             case 's' :    s = va_arg(arg, char *);
  172.                         if (F.altForm)
  173.                             {
  174.                             i = (unsigned char) *s++;
  175.                             if (F.havePrecision && i > F.precision) i = F.precision;
  176.                             }
  177.                         else
  178.                             {
  179.                             i = strlen(s);
  180.                             if (F.havePrecision && i > F.precision) i = F.precision;
  181.                             }
  182.                         break;
  183.  
  184.             case 'n' :    s = va_arg(arg, void *);
  185.                         if      (F.hSize) * (short *) s = nwritten;
  186.                         else if (F.lSize) * (long  *) s = nwritten;
  187.                         else              * (int   *) s = nwritten;
  188.                         continue;
  189.  
  190.                 //  oops - unknown conversion, abort
  191.  
  192.             case 'M': case 'N': case 'O': case 'P': case 'Q':
  193.             case 'R': case 'S': case 'T': case 'U': case 'V':
  194.             // (extra cases force this to be an indexed switch)
  195.             default: goto done;
  196.  
  197.             case '%' :
  198.             copy1    :    *sbuffer++ = c; ++nwritten; continue;
  199.             }
  200.  
  201.             //  pad on the left
  202.  
  203.         if (i < F.fieldWidth && !F.leftJustify)
  204.             do { *sbuffer++ = ' '; ++nwritten; } while (i < --F.fieldWidth);
  205.  
  206.             //  write the converted result
  207.  
  208.         for (j=0; j<i; j++) *sbuffer++ = *s++;
  209.         nwritten += i;
  210.  
  211.             //  pad on the right
  212.  
  213.         for (; i < F.fieldWidth; i++)
  214.             { *sbuffer++ = ' '; ++nwritten; }
  215.         }
  216.  
  217. done: return(nwritten);
  218.     }
  219.  
  220. void debug(char *format, ...)
  221.     {
  222.     unsigned char buffer[256];
  223.     va_list ptr;
  224.     va_start(ptr,format);
  225.     buffer[0] = vsprintf((char *)buffer+1, format, ptr);
  226.     va_end(ptr);
  227.     DebugStr(buffer);
  228.     }
  229.